﻿/**
 *
 * mstdio.c
 *
 *  Created on: 2019-09-05
 *      Author: chenshisheng
 */

#include <mstdio.h>
#include <serial.h>
#include <stdarg.h>

#include "message_queue.h"
#include "stream/chprintf.h"
#include "stream/serial_stream.h"
#include "active.h"

static SerialStream_t _stdio;

static bool _Rx(Serial_t serial, uint8_t b)
{
    Stream_t *stream;

    if(b == '\n')
    {
        // 发送消息给shell
        stream = & _stdio.stream;
        MsgQueue_Send(MsgQueue_Id_ShellLineIn, & stream, sizeof(stream));
    }

    return true;
}

static void _AtStart(Serial_t serial)
{
    UNUSED(serial);

    Active_Set(Active_Stdio, true);
}

static void _AtEnd(Serial_t serial)
{
    UNUSED(serial);

    Active_Set(Active_Stdio, false);
}

void MStdio_Init(void)
{
    SerialStream_Init(&_stdio, STDIO_SERIAL);
    Serial_SetCallbacks(STDIO_SERIAL, _AtStart, _AtEnd, _Rx);

    debug("MStdio Init\n");
}

int printf(const char *fmt, ...)
{
    va_list args;
    int n;

    va_start(args, fmt);
    Stream_MutexWait(& _stdio);
    n = chvprintf(& _stdio, fmt, args);
    Stream_MutexRelease(& _stdio);
    va_end(args);

    return n;
}

int vprintf(const char *fmt, va_list vargs)
{
    return chvprintf(&_stdio, fmt, vargs);
}

int puts(const char *str)
{
    int n = 0;

    Stream_MutexWait(& _stdio);
    while(*str != '\0')
    {
        n += _stdio.stream.put(& _stdio, *str++);
    }

    n += _stdio.stream.put(& _stdio, '\r');
    n += _stdio.stream.put(& _stdio, '\n');

    Stream_MutexRelease(& _stdio);
    return n;
}

Stream_t *Mstdio_Stream(void)
{
    return & (_stdio.stream);
}
